﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Speech.AudioFormat;
using System.Speech.Synthesis;
using System.Threading.Tasks;
using System.IO;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;

namespace TTSTest.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TextToSpeechController : ControllerBase
    {
        private readonly IWebHostEnvironment _hostingEnvironment;
        private readonly ILogger<TextToSpeechController> _logger;
        public TextToSpeechController(IWebHostEnvironment hostingEnvironment, ILogger<TextToSpeechController> logger)
        {
            _hostingEnvironment = hostingEnvironment;
            _logger = logger;
        }

        private static readonly object obj = new();

        [HttpGet]
        public ActionResult<string> get(string text, int speed = -3, string name = "")
        {
            try
            {
                if (speed > 10 || speed < -10)
                {
                    return new JsonResult(new { code = -1, msg = "语速设置异常，语速取值范围为-10 - 10！" });
                }
                _logger.LogInformation("生成语音入参:" + text);
                lock (obj)
                {
                    if (text.Length > 65535)
                    {
                        return new JsonResult(new { code = 1, msg = "文字长度太长了，请将文字控制在65535个字符之内！", url = "" });
                    }
                    text = GetVoidText(text, name);
                    string fileName = GetMD5(text);
                    string filePath = _hostingEnvironment.ContentRootPath + $"\\wwwroot\\speech\\{fileName}.wav";
                    if (System.IO.File.Exists(filePath))
                    {
                        return new JsonResult(new { code = 0, msg = "语音存在了！", url = $"/speech/{fileName}.wav" });
                    }
                    else
                    {
                        try
                        {
                            using SpeechSynthesizer synth = new();
                            synth.Rate = speed;
                            synth.Volume = 100;
                            synth.SetOutputToWaveFile(filePath, new SpeechAudioFormatInfo(32000, AudioBitsPerSample.Sixteen, AudioChannel.Mono));
                            PromptBuilder builder = new();
                            builder.AppendAudio(_hostingEnvironment.ContentRootPath + $"\\wwwroot\\speech\\notification.wav");
                            builder.AppendText(text);
                            synth.Speak(builder);
                        }
                        catch (Exception e)
                        {
                            _logger.LogInformation("生成语音异常:" + e.Message);
                            return new JsonResult(new { code = -1, msg = "生成语音异常！", url = $"/speech/{fileName}.wav" });
                        }
                        return new JsonResult(new { code = 0, msg = "生成语音成功！", url = $"/speech/{fileName}.wav" });
                    }
                }
            }
            catch (Exception e)
            {
                return new JsonResult(new { code = -1, msg = "生成语音失败了！", url = e });
            }

        }

        private string GetMD5(string myString)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] fromData = System.Text.Encoding.Unicode.GetBytes(myString);
            byte[] targetData = md5.ComputeHash(fromData);
            string byte2String = null;
            for (int i = 0; i < targetData.Length; i++)
            {
                byte2String += targetData[i].ToString("x");
            }
            return byte2String;
        }
        /// <summary>
        /// 对输入的文字进行处理
        /// </summary>
        /// <returns></returns>
        private string GetVoidText(string text, string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return text;
            }
            string familyName = name.Substring(0, 1);
            var newFamilyName = familyName
                   .Replace("解", "谢")
                   .Replace("单", "善")
                   .Replace("柏", "佰")
                   .Replace("鲍", "报")
                   .Replace("贲", "奔")
                   .Replace("秘", "币")
                   .Replace("薄", "博")
                   .Replace("卜", "补")
                   .Replace("晁", "潮")
                   .Replace("谌", "陈")
                   .Replace("种", "重")
                   .Replace("秘", "币")
                   .Replace("褚", "储")
                   .Replace("啜", "踹")
                   .Replace("秘", "币")
                   .Replace("郗", "吃")
                   .Replace("邸", "底")
                   .Replace("都", "都")
                   .Replace("费", "费")
                   .Replace("苻", "服")
                   .Replace("干", "干")
                   .Replace("杲", "搞")
                   .Replace("戈", "哥")
                   .Replace("艮", "亘")
                   .Replace("妫", "归")
                   .Replace("缑", "勾")
                   .Replace("都", "都")
                   .Replace("晟", "圣")
                   .Replace("郜", "告")
                   .Replace("句", "苟")
                   .Replace("华", "桦")
                   .Replace("靳", "进")
                   .Replace("宓", "蜜")
                   .Replace("缪", "妙")
                   .Replace("牟", "眸")
                   .Replace("邳", "批")
                   .Replace("朴", "瓢")
                   .Replace("繁", "泼")
                   .Replace("莆", "扑")
                   .Replace("繁", "泼")
                   .Replace("戚", "七")
                   .Replace("谯", "乔")
                   .Replace("覃", "亲")
                   .Replace("仇", "求")
                   .Replace("曲", "屈")
                   .Replace("任", "人")
                   .Replace("阮", "软")
                   .Replace("芮", "瑞")
                   .Replace("少", "哨")
                   .Replace("召", "哨")
                   .Replace("佘", "舍")
                   .Replace("厍", "舍")
                   .Replace("莘", "申")
                   .Replace("折", "蛇")
                   .Replace("折", "乔")
                   .Replace("佟", "同")
                   .Replace("郤", "细")
                   .Replace("冼", "显")
                   .Replace("洗", "显")
                   .Replace("郇", "还")
                   .Replace("乐", "月")
                   .Replace("查", "渣")
                   .Replace("曾", "增");
            Regex r = new(familyName);
            return r.Replace(text, newFamilyName, 1);
        }
    }
}
